﻿using SuperMap.Realspace;
using SuperMap.UI;
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;
using Ycjw.PipeLine.BigScreen;
using Ycjw.PipeLine.Map;
using Ycjw.PipeLine.Map.Basic;

namespace Ycjw.PipeLine.Scenes
{    
    /****************************************************************************************/
    /*
    功    能:
    作    者: RenZachary
    联系方式: rzcgis@foxmail.com（QQ455745253）
    生成日期: 2021年3月24日
    修改日志: 
    版权说明: @2021 西安云创经纬信息科技有限公司 版权所有 All right reserved.
    注    意: 本内容仅限于云创经纬公司内部使用，禁止用于商业目的。
    */
    /****************************************************************************************/
    public class SceneAdapter
    {
        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        FullScreeFrameworkEx2 m_FullScreeFramework;
        FullScreeFrameworkRealTime m_FullScreeFrameworkRealTime;
        //定义委托
        public delegate void OpenHandle(SceneControl sceneControl);
        //定义事件
        public event OpenHandle NewOpenEvent;
        static SceneAdapter m_Instance;

        private SceneEx m_SceneEx;
        private Control ControlForCenter = null;
        Timer m_Timeer = null;
        public SceneEx SceneEx
        {
            get
            {
                return m_SceneEx;
            }
        }
        public void OpenWorkSpace(string path = "")
        {
            WorkSpaceEx wse = new WorkSpaceEx();
            wse.Open(m_SceneEx.Scene, path);
            NewOpenEvent?.Invoke(SceneControl);
            SceneControl.Action = Action3D.Pan;
        }
        public SceneControl SceneControl
        {
            get
            {
                if (this.m_SceneEx != null)
                    return m_SceneEx.SceneControl;
                return null;
            }
        }
        public Scene Scene
        {
            get
            {
                if (this.m_SceneEx != null)
                    return m_SceneEx.Scene;
                return null;
            }
        }
        public void CloseWorkSpace()
        {
            WorkSpaceEx wse = new WorkSpaceEx();
            wse.Close(m_SceneEx.Scene);
        }
        public static SceneAdapter Instance
        {
            get
            {
                if (m_Instance == null) m_Instance = new SceneAdapter();
                return m_Instance;
            }
        }
        public void LoadSceneControl(DockPanel dp)
        {
            m_SceneEx = new SceneEx
            {
                MdiParent = FormMainRibbon.Instance,
                FormBorderStyle = System.Windows.Forms.FormBorderStyle.None,
                MaximizeBox = false,
                MinimizeBox = false,
                ControlBox = false,
                Dock = System.Windows.Forms.DockStyle.Fill
            };
            m_SceneEx.SetDockPanel(dp);
            m_SceneEx.Show();
            //AddEventKeyUp(m_SceneEx);
        }
        public void RealTime()
        {
            if (this.m_FullScreeFrameworkRealTime == null)
            {
                m_FullScreeFrameworkRealTime = new FullScreeFrameworkRealTime
                {
                    SceneControl = SceneControl,
                    EscClose = false
                };
                m_SceneEx.SceneControl.ObjectSelected += SceneControl_ObjectSelected;
                m_FullScreeFrameworkRealTime.VisibleChanged += FullScreeFramework_VisibleChanged;
            }
            m_FullScreeFrameworkRealTime.Show();
            LoadSceneControlToFullScreenOfRealTime();
        }
        public void FullScreen()
        {
            if (m_FullScreeFramework == null)
            {
                m_FullScreeFramework = new FullScreeFrameworkEx2
                {
                    SceneControl = SceneControl,
                    EscClose = false
                };
                m_SceneEx.SceneControl.ObjectSelected += SceneControl_ObjectSelected;
                m_FullScreeFramework.VisibleChanged += FullScreeFramework_VisibleChanged;
            }
            m_FullScreeFramework.Show();
            LoadSceneControlToFullScreen();
            //m_FullScreeFramework.AddScreenLayer();
            //DynamicLook(true);
        }

        private void FullScreeFramework_VisibleChanged(object sender, EventArgs e)
        {
            if(sender is FullScreeFrameworkEx2 && this.m_FullScreeFramework.Visible == false)
            {
                ExitFullScreen();
            }
            if (sender is FullScreeFrameworkRealTime && this.m_FullScreeFrameworkRealTime.Visible == false)
            {
                ExitFullScreenOfRealTime();
            }
        }

        private void SceneControl_ObjectSelected(object sender, ObjectSelectedEventArgs e)
        {
            DynamicLook(false);
        }

        private void DynamicLook(bool dynamic) 
        {
            if(m_Timeer == null)
            {
                m_Timeer = new Timer()
                {
                    Interval = 100
                };
                m_Timeer.Tick += Timeer_Tick;
            }
            if (dynamic) m_Timeer.Start();
            else m_Timeer.Stop();
        }

        private void Timeer_Tick(object sender, EventArgs e)
        {
            var lookAtStart = m_SceneEx.Scene.LookAt;
            if (double.IsNaN(lookAtStart.Longitude)) return;
            var newLookAt = new LookAt()
            {
                Longitude = lookAtStart.Longitude,
                Latitude = lookAtStart.Latitude,
                Tilt = lookAtStart.Tilt,
                Range = lookAtStart.Range,
                AltitudeMode = lookAtStart.AltitudeMode,
                Altitude = lookAtStart.Altitude,
                Heading = lookAtStart.Heading
            };
            var lookAtHeading = lookAtStart.Heading;
            var newHeading = lookAtHeading + 1;
            if (newHeading > 360) newHeading -= 360;
            newLookAt.Heading = newHeading;

            m_SceneEx.Scene.LookAt = newLookAt;
        }
        private void LoadSceneControlToFullScreen()
        {
            var centerPanel = m_FullScreeFramework.GetCenterPanel();
            centerPanel.Controls.Add(m_SceneEx.SceneControl);

            ControlForCenter = centerPanel.Controls[centerPanel.Controls.Count - 1];
        }
        private void LoadSceneControlToFullScreenOfRealTime()
        {
            var centerPanel = m_FullScreeFrameworkRealTime.GetCenterPanel();
            centerPanel.Controls.Add(m_SceneEx.SceneControl);

            ControlForCenter = centerPanel.Controls[centerPanel.Controls.Count - 1];
        }
        public void ExitFullScreen()
        {
            this.SceneControl.Scene.ScreenLayer.Clear();
            DynamicLook(false);
            m_SceneEx.Controls.Add(ControlForCenter);

            if (m_FullScreeFramework != null && !m_FullScreeFramework.IsDisposed) m_FullScreeFramework.Visible = false;
        }

        public void ExitFullScreenOfRealTime()
        {
            this.SceneControl.Scene.ScreenLayer.Clear();
            DynamicLook(false);
            m_SceneEx.Controls.Add(ControlForCenter);

            if (m_FullScreeFrameworkRealTime != null && !m_FullScreeFrameworkRealTime.IsDisposed) m_FullScreeFrameworkRealTime.Visible = false;
        }

        private void AddEventKeyUp(Control control)
        {
            if (control != null)
            {
                control.KeyUp += new KeyEventHandler(Control_KeyUp);
                foreach (Control c in control.Controls)
                {
                    AddEventKeyUp(c);
                }
            }
        }

        void Control_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Escape)
            {
                this.ExitFullScreen();
            }

        }
    }
}
